home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / gfx / show / h8ilbm.lha / h8ilbm / src / h8ilbm.c < prev    next >
C/C++ Source or Header  |  2000-12-16  |  23KB  |  590 lines

  1. /*****************************************************************************
  2.  
  3.     h8ilbm - HiQuality-HAM8 IFF-24bit image viewer
  4.     Copyright (C) 2000  Michael Henke
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20. *****************************************************************************/
  21.  
  22.  
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <proto/exec.h>
  26. #include <proto/dos.h>
  27. #include <proto/graphics.h>
  28. #include <proto/intuition.h>
  29. #include <exec/memory.h>
  30. #include <exec/interrupts.h>
  31. #include <graphics/displayinfo.h>
  32. #include <proto/reqtools.h>
  33. #include <proto/asyncio.h>
  34. #include <libraries/reqtools.h>
  35. #include <libraries/asyncio.h>
  36. #include <intuition/intuition.h>
  37. #include <intuition/screens.h>
  38. #include <devices/inputevent.h>
  39.  
  40.  
  41. UBYTE version[]="$VER: h8ilbm 0.1 (Sat 16-Dec-2000)";
  42. UBYTE template[]="FILES/M,MID/K,SMR/S", rtfilename[128];
  43. UBYTE rowbuf0[16*1024*3];
  44. struct RDArgs *rdargs=NULL;
  45. LONG args[3]={0,0,0};
  46. struct ReqToolsBase *ReqToolsBase=NULL;
  47. struct Library *AsyncIOBase=NULL;
  48. WORD ende=0, movekey=0, xoff, yoff;
  49.  
  50.  
  51. int check_idcmp(void);
  52. extern void __asm render_h8row( register __a0 UBYTE *rowbuf,
  53.                                 register __d0 UWORD iw16,
  54.                                 register __a1 struct BitMap *bmap,
  55.                                 register __d1 UWORD row );
  56. BOOL alloc_chipmem(UWORD scr_w, UWORD scr_h);  /*return: success*/
  57. void free_chipmem(UWORD scr_w, UWORD scr_h);
  58.  
  59.  
  60. struct DimensionInfo diminfo;
  61. struct BitMap bmap=
  62. {
  63.     2, 2,               /* BytesPerRow, Rows */
  64.     0, 8, 0,            /* Flags, Depth, pad */
  65.     0,0,0,0,0,0,0,0     /* Planes */
  66. };
  67. struct Interrupt window_int=
  68. {
  69.     NULL,NULL, NT_UNKNOWN, 0, NULL,     /* struct Node */
  70.     NULL,(void(*)(void))check_idcmp
  71. };
  72. struct NewScreen newscr=
  73. {
  74.     0, 0, 99, 99, 8,    /* LeftEdge, TopEdge, Width, Height, Depth */
  75.     0, 0, 0,            /* DetailPen, BlockPen, ViewModes */
  76.     AUTOSCROLL|SCREENQUIET|SCREENHIRES|CUSTOMBITMAP|CUSTOMSCREEN|SCREENBEHIND,   /* Type */
  77.     0, 0, 0, &bmap      /* Font, DefaultTitle, Gadgets, CustomBitMap */
  78. };
  79. struct NewWindow newwin=
  80. {
  81.     0, 0, 99, 99,       /* LeftEdge, TopEdge, Width, Height */
  82.     0, 0,               /* DetailPen, BlockPen */
  83.     IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS,   /* IDCMPFlags */
  84.     WFLG_RMBTRAP|WFLG_NOCAREREFRESH|WFLG_ACTIVATE|WFLG_BORDERLESS|WFLG_BACKDROP,    /* Flags */
  85.     0, 0, 0,            /* FirstGadget, CheckMark, Title */
  86.     0, 0,               /* Screen, BitMap */
  87.     0, 0, 0, 0,         /* MinWidth, MinHeight, MaxWidth, MaxHeight */
  88.     CUSTOMSCREEN        /* Type */
  89. };
  90. static ULONG palette[]=
  91. {
  92.     1<<16,              /* (count<<16)+first */
  93.     0x00000000,0x00000000,0x00000000,
  94.     0                   /* end marker */
  95. };
  96. struct Screen *myscreen=NULL;
  97. struct Window *mywindow=NULL;
  98.  
  99.  
  100. #define ID_FORM 0x464F524D
  101. #define ID_ILBM 0x494C424D
  102. #define ID_BMHD 0x424D4844
  103. #define ID_BODY 0x424F4459
  104.  
  105.  
  106.  
  107. int main(void)
  108. {
  109.     int rc=0;
  110.     UBYTE **files_pt, *filename, **rowbuf;
  111.     ULONG modeid, header[3], r1;
  112.     UWORD iw, ih, id, ic, im, v_scr_w, scr_w, v_scr_h, scr_h, scr_w64, iw16, bufmode;
  113.     struct rtFileRequester *rtfilereq=NULL;
  114.     struct rtFileList *rtfilelist=NULL, *rtfilelist_curr=NULL;
  115.     BPTR lock_newdir=NULL, lock_olddir=NULL;
  116.     struct AsyncFile *file=NULL;
  117.  
  118.     /*****************************
  119.     ** read command line arguments
  120.     ******************************/
  121.     rdargs=ReadArgs(template,args,NULL);
  122.     printf("\33[1m%s by Smack/Infect!\33[0m\n",&version[6]);
  123.     if (!(AsyncIOBase=OpenLibrary("asyncio.library",39)))
  124.     {
  125.         printf("**unable to open asyncio.library V39+\n");
  126.         rc=20; goto exit_clean;
  127.     }
  128.     files_pt=(UBYTE**)args[0];
  129.     modeid=0x8020;
  130.     if(args[1])
  131.     {
  132.         int b=10;
  133.         UBYTE *pt=(UBYTE*)args[1];
  134.         if(pt[0]=='$') {pt++; b=16;}
  135.         if((pt[0]=='0')&&((pt[1]=='x')||(pt[1]=='X'))) {pt+=2; b=16;}
  136.         modeid=strtoul(pt,NULL,b);
  137.     }
  138.     if(ModeNotAvailable(modeid))
  139.     {
  140.         printf("**screen mode not available: 0x%x\n",modeid);
  141.         args[2]=1;
  142.     }
  143.  
  144.     /**********************
  145.     ** screenmode requester
  146.     ***********************/
  147.     if(args[2])
  148.     {
  149.         if((ReqToolsBase=(struct ReqToolsBase*)OpenLibrary("reqtools.library",38)))
  150.         {
  151.             struct rtScreenModeRequester *rtsmreq;
  152.             if((rtsmreq=rtAllocRequest(RT_SCREENMODEREQ,NULL)))
  153.             {
  154.                 int res=rtScreenModeRequest(rtsmreq, "h8ilbm: select HAM8 screen mode", TAG_DONE);
  155.                 modeid=rtsmreq->DisplayID;
  156.                 rtFreeRequest(rtsmreq);
  157.                 if(!res) goto exit_clean;
  158.             }
  159.             else
  160.             {
  161.                 rc=10; goto exit_clean;
  162.             }
  163.         }
  164.         else
  165.         {
  166.             rc=5; goto exit_clean;
  167.         }
  168.     }
  169.     v_scr_w=v_scr_h=0;
  170.     if(GetDisplayInfoData(NULL,(UBYTE*)&diminfo,sizeof(struct DimensionInfo),DTAG_DIMS,modeid))
  171.     {
  172.         v_scr_w=diminfo.TxtOScan.MaxX-diminfo.TxtOScan.MinX+1;
  173.         v_scr_h=diminfo.TxtOScan.MaxY-diminfo.TxtOScan.MinY+1;
  174.     }
  175.     printf("  screen mode: MID=0x%x (%d x %d pixels visible)\n",modeid,v_scr_w,v_scr_h);
  176.  
  177.     /*************************
  178.     ** allocate file requester
  179.     **************************/
  180.     if(!files_pt)
  181.     {
  182.         if(!ReqToolsBase) ReqToolsBase=(struct ReqToolsBase*)OpenLibrary("reqtools.library",38);
  183.         if(ReqToolsBase)
  184.         {
  185.             if(!(rtfilereq=rtAllocRequest(RT_FILEREQ,NULL)))
  186.             {
  187.                 rc=10; goto exit_clean;
  188.             }
  189.         }
  190.         else
  191.         {
  192.             rc=5; goto exit_clean;
  193.         }
  194.     }
  195.  
  196.     /****************
  197.     ** file requester
  198.     *****************/
  199. next_filereq:
  200.     if(rtfilereq)
  201.     {
  202.         if(rtfilelist) rtFreeFileList(rtfilelist);
  203.         rtfilelist=rtFileRequest( rtfilereq, &rtfilename[0],
  204.                                   "h8ilbm: select IFF-24bit images",
  205.                                   RTFI_Flags, FREQF_MULTISELECT|FREQF_PATGAD,
  206.                                   TAG_DONE );
  207.         if(rtfilelist)
  208.         {
  209.             rtfilelist_curr=rtfilelist;
  210.             if(rtfilereq->Dir)
  211.             {
  212.                 lock_newdir=Lock(rtfilereq->Dir,SHARED_LOCK);
  213.                 lock_olddir=CurrentDir(lock_newdir);
  214.             }
  215.         }
  216.         else goto exit_clean;
  217.     }
  218.  
  219.     /****************************************
  220.     ** the main loop: display all input files
  221.     *****************************************/
  222.     do
  223.     {
  224.         if(rtfilelist)
  225.         {
  226.             if(rtfilelist_curr)
  227.             {
  228.                 filename=rtfilelist_curr->Name;
  229.                 rtfilelist_curr=rtfilelist_curr->Next;
  230.             }
  231.             else filename=NULL;
  232.         }
  233.         else filename=(*files_pt++);
  234.         if(!filename) break;
  235.         printf("\n  file: %s\n",filename);
  236.  
  237.         if((file=OpenAsync(filename,MODE_READ,64*1024)))
  238.         {
  239.             r1=ReadAsync(file,header,3*4);
  240.             if((r1==3*4) && (header[0]==ID_FORM) && (header[2]==ID_ILBM))
  241.             {
  242.                 /*************************
  243.                 ** read IFF-ILBM file info
  244.                 **************************/
  245.                 WORD body_found=0, type_error=0;
  246.                 iw=ih=id=ic=im=0;
  247.                 do
  248.                 {
  249.                     r1=ReadAsync(file,header,2*4);
  250.                     if(r1!=2*4) type_error=1;
  251.                     else switch(header[0])
  252.                     {
  253.                         case ID_BODY:
  254.                             body_found=1;
  255.                             break;
  256.                         case ID_BMHD:
  257.                             if(header[1]!=20) type_error=2;
  258.                             ReadAsync(file,&iw,2);
  259.                             ReadAsync(file,&ih,2);
  260.                             SeekAsync(file,4,MODE_CURRENT); /*skip x,y*/
  261.                             id=ReadCharAsync(file);
  262.                             im=ReadCharAsync(file); if(im!=1) im=0;
  263.                             ic=ReadCharAsync(file);
  264.                             SeekAsync(file,9,MODE_CURRENT); /*skip rest*/
  265.                             break;
  266.                         default:
  267.                             SeekAsync(file,header[1],MODE_CURRENT);
  268.                     }
  269.                 } while(!body_found && !type_error);
  270.                 printf("  type: %d x %d, %d bits%s%s\n",iw,ih,id,(ic==1)?", ByteRun1 compression":"",im?", masking bitplane":"");
  271.                 if(body_found && !type_error && iw && ih && (id==24) && (ic<=1))
  272.                 {
  273.                     UWORD row;
  274.                     /**********************
  275.                     ** allocate chip memory
  276.                     ***********************/
  277.                     bufmode=0;
  278.                     iw16=(iw+15)&(~15);
  279.                     scr_w=iw*4; scr_h=ih;
  280.                     scr_w64=(scr_w+63)&(~63);
  281.                     if(!alloc_chipmem(scr_w64,scr_h))
  282.                     {
  283.                         printf("  not enough chip memory for rendered image, switching to buffer mode\n");
  284.                         bufmode=1;
  285.                         scr_w=v_scr_w; scr_h=v_scr_h;
  286.                         scr_w64=(scr_w+63)&(~63);
  287.                         if(!alloc_chipmem(scr_w64,scr_h))
  288.                         {
  289.                             printf("**not enough chip memory for screen.\n");
  290.                             ende=(-1); /*next image*/
  291.                         }
  292.                     }
  293.  
  294.                     /*****************************
  295.                     ** allocate fast memory buffer
  296.                     ******************************/
  297.                     if(bufmode && !ende)
  298.                     {
  299.                         rowbuf=AllocMem((ULONG)(ih*sizeof(UBYTE*)),MEMF_CLEAR|MEMF_PUBLIC);
  300.                         for(row=0;row<ih;row++) if(!(rowbuf[row]=AllocMem(((ULONG)iw16*18L)>>3,MEMF_PUBLIC))) break;
  301.                         if(row<ih)
  302.                         {
  303.                             printf("**not enough memory for image buffer.\n");
  304.                             ende=(-1); /*next image*/
  305.                         }
  306.                     }
  307.  
  308.                     /************************
  309.                     ** open screen and window
  310.                     *************************/
  311.                     if(!ende)
  312.                     {
  313.                         newscr.Width=scr_w;
  314.                         newscr.Height=scr_h;
  315.                         myscreen=OpenScreenTags(&newscr,
  316.                                                 SA_DisplayID,modeid|HAM_KEY,
  317.                                                 SA_Colors32,palette,
  318.                                                 SA_Overscan,OSCAN_TEXT,
  319.                                                 SA_BackFill,1, /*LAYERS_NOBACKFILL*/
  320.                                                 TAG_END,0);
  321.                         if(!myscreen)
  322.                         {
  323.                             printf("**unable to open screen\n");
  324.                             ende=(-1); /*next image*/
  325.                         }
  326.                     }
  327.                     if(!ende)
  328.                     {
  329.                         newwin.Screen=myscreen;
  330.                         newwin.Width=scr_w;
  331.                         newwin.Height=scr_h;
  332.                         mywindow=OpenWindowTags(&newwin,
  333.                                                 WA_BackFill,1, /*LAYERS_NOBACKFILL*/
  334.                                                 TAG_END,0);
  335.                         if(!mywindow)
  336.                         {
  337.                             printf("**unable to open window\n");
  338.                             ende=(-1); /*next image*/
  339.                         }
  340.                     }
  341.                     if(!ende)
  342.                     {
  343.                         LONG il;
  344.                         ULONG *ulpt;
  345.                         Disable();
  346.                         mywindow->UserPort->mp_Flags=PA_SOFTINT;
  347.                         mywindow->UserPort->mp_SigTask=(void*)&window_int;
  348.                         Enable();
  349.                         ulpt=(ULONG*)bmap.Planes[6];
  350.                         for(il=(LONG)(scr_w64/32)*(LONG)scr_h;il>0;il--) *ulpt++ = 0x77777777;
  351.                         ulpt=(ULONG*)bmap.Planes[7];
  352.                         for(il=(LONG)(scr_w64/32)*(LONG)scr_h;il>0;il--) *ulpt++ = 0xcccccccc;
  353.                         ScreenToFront(myscreen);
  354.                     }
  355.  
  356.                     /*****************
  357.                     ** read image data
  358.                     ******************/
  359.                     if(!ende)
  360.                     {
  361.                         UWORD plane, bpr=iw16>>3;
  362.                         UBYTE *rowpt, *rowpt0;
  363.                         xoff=yoff=0;
  364.                         if(ic==0)   /** compression==cmpNone **/
  365.                         {
  366.                             for(row=0;row<ih;row++)
  367.                             {
  368.                                 if(ende) break;
  369.                                 if(bufmode) rowpt0=rowbuf[row]; else rowpt0=rowbuf0;
  370.                                 rowpt=rowpt0;
  371.                                 for(plane=0;plane<24;plane++)
  372.                                 {
  373.                                     if((plane%8)>1)
  374.                                     {
  375.                                         ReadAsync(file,rowpt,(LONG)bpr);
  376.                                         rowpt+=bpr;
  377.                                     }
  378.                                     else SeekAsync(file,(LONG)bpr,MODE_CURRENT);
  379.                                 }
  380.                                 if(row<scr_h) render_h8row(rowpt0,iw16,&bmap,row);
  381.                                 if(im) SeekAsync(file,(LONG)bpr,MODE_CURRENT);
  382.                             }
  383.                         }
  384.                         else /*if(ic==1)*/  /** compression==cmpByteRun1 **/
  385.                         {
  386.                             WORD code, bytes;
  387.                             UBYTE *rowpt2, repeat;
  388.                             for(row=0;row<ih;row++)
  389.                             {
  390.                                 if(ende) break;
  391.                                 if(bufmode) rowpt0=rowbuf[row]; else rowpt0=rowbuf0;
  392.                                 rowpt=rowpt0;
  393.                                 for(plane=0;plane<24;plane++)
  394.                                 {
  395.                                     rowpt2=rowpt;
  396.                                     bytes=bpr;
  397.                                     if((plane%8)>1)
  398.                                     {
  399.                                         while(bytes>0)
  400.                                         {
  401.                                             if((code=ReadCharAsync(file))<0) break;
  402.                                             if(code<=127)
  403.                                             {
  404.                                                 code++; bytes-=code;
  405.                                                 ReadAsync(file,rowpt2,(LONG)code);
  406.                                                 rowpt2+=code;
  407.                                             }
  408.                                             else
  409.                                             {
  410.                                                 code=257-code; bytes-=code;
  411.                                                 repeat=ReadCharAsync(file);
  412.                                                 while(code>0) {*rowpt2++=repeat; code--;}
  413.                                             }
  414.                                         }
  415.                                         rowpt+=bpr;
  416.                                     }
  417.                                     else
  418.                                     {
  419.                                         while(bytes>0)
  420.                                         {
  421.                                             if((code=ReadCharAsync(file))<0) break;
  422.                                             if(code<=127)
  423.                                             {
  424.                                                 code++;
  425.                                                 SeekAsync(file,(LONG)code,MODE_CURRENT);
  426.                                                 bytes-=code;
  427.                                             }
  428.                                             else
  429.                                             {
  430.                                                 bytes-=257-code;
  431.                                                 ReadCharAsync(file);
  432.                                             }
  433.                                         }
  434.                                     }
  435.                                 }
  436.                                 if(row<scr_h) render_h8row(rowpt0,iw16,&bmap,row);
  437.                                 if(im)
  438.                                 {
  439.                                     bytes=bpr;
  440.                                     while(bytes>0)
  441.                                     {
  442.                                         if((code=ReadCharAsync(file))<0) break;
  443.                                         if(code<=127)
  444.                                         {
  445.                                             code++;
  446.                                             SeekAsync(file,(LONG)code,MODE_CURRENT);
  447.                                             bytes-=code;
  448.                                         }
  449.                                         else
  450.                                         {
  451.                                             bytes-=257-code;
  452.                                             ReadCharAsync(file);
  453.                                         }
  454.                                     }
  455.                                 }
  456.                             }
  457.                         }
  458.                     }
  459.  
  460.                     /***************
  461.                     ** display image
  462.                     ****************/
  463.                     while(!ende)
  464.                     {
  465.                         if(movekey)
  466.                         {
  467.                             movekey=0;
  468.                             if(bufmode)
  469.                             {
  470.                                 WORD xoff2, yoff2, dh=(scr_h<ih) ? scr_h : ih;
  471.                                 if(xoff<0) xoff=0;
  472.                                 if(yoff<0) yoff=0;
  473.                                 if(xoff+scr_w64/4>iw16) xoff=iw16-scr_w64/4;
  474.                                 if(yoff+scr_h>ih) yoff=ih-scr_h;
  475.                                 if(iw16<scr_w64/4) xoff=0;
  476.                                 if(ih<scr_h) yoff=0;
  477.                                 xoff2=xoff, yoff2=yoff;
  478.                                 for(row=0;row<dh;row++) render_h8row(rowbuf[row+yoff2]+xoff2/8,iw16,&bmap,row);
  479.                             }
  480.                             else
  481.                             {
  482.                                 MoveScreen(myscreen,(LONG)(-xoff),(LONG)(-yoff));
  483.                                 xoff=yoff=0;
  484.                             }
  485.                         }
  486.                         else Delay(1);
  487.                     }
  488.                     if(ende<0) ende=0; /*next image*/
  489.  
  490.                     /****************
  491.                     ** free resources
  492.                     *****************/
  493.                     if(mywindow) {CloseWindow(mywindow); mywindow=NULL;}
  494.                     if(myscreen) {CloseScreen(myscreen); myscreen=NULL;}
  495.                     if(bufmode)
  496.                     {
  497.                         for(row=0;row<ih;row++) if(rowbuf[row]) FreeMem(rowbuf[row],((ULONG)iw16*18L)>>3);
  498.                         FreeMem(rowbuf,(ULONG)(ih*sizeof(UBYTE*)));
  499.                     }
  500.                     free_chipmem(scr_w64,scr_h);
  501.                 }
  502.                 else printf("**file type not supported\n");
  503.             }
  504.             else printf("**not an IFF ILBM file\n");
  505.             CloseAsync(file); file=NULL;
  506.         }
  507.         else printf("**unable to open file\n");
  508.     } while(!ende);
  509.  
  510.     if(rtfilelist)
  511.     {
  512.         if(lock_olddir) { CurrentDir(lock_olddir); lock_olddir=NULL; }
  513.         if(lock_newdir) { UnLock(lock_newdir); lock_newdir=NULL; }
  514.         if(!ende) goto next_filereq;
  515.     }
  516.  
  517. exit_clean:
  518.     if(file) CloseAsync(file);
  519.     if(lock_olddir) CurrentDir(lock_olddir);
  520.     if(lock_newdir) UnLock(lock_newdir);
  521.     if(rtfilelist) rtFreeFileList(rtfilelist);
  522.     if(rtfilereq) rtFreeRequest(rtfilereq);
  523.     if(ReqToolsBase) CloseLibrary((struct Library*)ReqToolsBase);
  524.     if(AsyncIOBase) CloseLibrary(AsyncIOBase);
  525.     if(rdargs) FreeArgs(rdargs);
  526.     return(rc);
  527. }
  528.  
  529.  
  530.  
  531.  
  532. int __saveds check_idcmp(void)
  533. {
  534.     WORD dist;
  535.     struct IntuiMessage *msg;
  536.     while((msg=(struct IntuiMessage*)GetMsg(mywindow->UserPort)))
  537.     {
  538.         switch(msg->Class)
  539.         {
  540.         case IDCMP_RAWKEY:
  541.             dist=8;
  542.             if((msg->Qualifier&IEQUALIFIER_LSHIFT)||(msg->Qualifier&IEQUALIFIER_RSHIFT)) dist=32;
  543.             if((msg->Qualifier&IEQUALIFIER_LALT)||(msg->Qualifier&IEQUALIFIER_RALT)) dist=9999;
  544.             switch(msg->Code)
  545.             {
  546.                 case 0x45: /*ESC*/   ende=1; break;
  547.                 case 0x44: /*Return*/
  548.                 case 0x40: /*Space*/ ende=(-1); break;
  549.                 case 0x4c: /*up*/    yoff-=dist; movekey=msg->Code; break;
  550.                 case 0x4d: /*down*/  yoff+=dist; movekey=msg->Code; break;
  551.                 case 0x4e: /*right*/ xoff+=dist; movekey=msg->Code; break;
  552.                 case 0x4f: /*left*/  xoff-=dist; movekey=msg->Code; break;
  553.             }
  554.             break;
  555.         case IDCMP_MOUSEBUTTONS:
  556.             switch(msg->Code)
  557.             {
  558.                 case MENUUP: /*right MB*/ ende=(-1); break;
  559.             }
  560.             break;
  561.         }
  562.         ReplyMsg((struct Message*)msg);
  563.     }
  564.     return(0);
  565. }
  566.  
  567. BOOL alloc_chipmem(UWORD scr_w, UWORD scr_h)
  568. {
  569.     int i;
  570.     bmap.BytesPerRow=scr_w/8;
  571.     bmap.Rows=scr_h;
  572.     for(i=0;i<8;i++) if(!(bmap.Planes[i]=AllocMem((LONG)(scr_w/8)*(LONG)scr_h,MEMF_CHIP|MEMF_CLEAR))) break;
  573.     if(i<8)
  574.     {
  575.         free_chipmem(scr_w,scr_h);
  576.         return(FALSE);
  577.     }
  578.     else return(TRUE);
  579. }
  580.  
  581. void free_chipmem(UWORD scr_w, UWORD scr_h)
  582. {
  583.     int i;
  584.     for(i=0;i<8;i++)
  585.     {
  586.         if(bmap.Planes[i]) FreeMem(bmap.Planes[i],(LONG)(scr_w/8)*(LONG)scr_h);
  587.         bmap.Planes[i]=NULL;
  588.     }
  589. }
  590.